// userexits.cpp
// Customizer_Base
// Protea Customizer/Customizer Pro / Business Logic for managing user exits
// Copyright (C) 2003, 2004, 2005 eXegeSys, Inc.
// Copyright (C) 2008 Bruce A. James
//
// This program is part of the Protea Project.
//
// The Protea Project is free software; you can redistribute it and/or modify it 
// under the terms of the GNU General Public License as published by the 
// Free Software Foundation, either version 3 of the License, or (at your 
// option) any later version.
//
// The Protea Project is distributed in the hope that it will be useful, but 
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
// for more details.
// 
// You should have received a copy of the GNU General Public License along 
// with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// Please send correspondence to:
//
// theproteaproject@gmail.com
//

#include "base_setup.h"

// USER_EXIT_DEFNS Subtransactions
//
//////////////////////////////////////////////////////////////////////////////



//@ SEC 3
//@ CHA User Exit List
//@ COD UserExitList
//@ TAB USER_EXIT_DEFNS Read
//@ GEN Helper function to return user exit list based on trans_code
XCDBStatement* UserExitList( XCBuffer* buf, XCTransactionVars* vars ) {
	XCSQLGen* query = vars->query;

	long fcount = 0;

	XCField* WhereList[4];
	XCCompare complist[4];

	//@ Convert the trans code into a number
	XCField* trans_code = vars->buffer->GetField( FLD_TRANS_CODE );
	if (trans_code && !trans_code->IsBlank()) {
		if (LookupNumberFromName( vars, vars->buffer, buf, FLD_TRANS_NUMBER, FLD_TRANS_CODE, FMT_TRANSACTION_DEFN )) {
			WhereList[fcount++] = buf->GetField( FLD_TRANS_NUMBER );
		};
	};

	// Formulate select statement
	query->MakeSELECT( buf );

	// If Appl_nbr = 0, select all records
	XCField* temp = buf->GetField( FLD_APPL_NBR );
	if (temp->Compare(0) != 0)
		WhereList[fcount++] = buf->GetField( FLD_APPL_NBR );

	// Do we have any search criteria?
	if (fcount) {
		WhereList[fcount++] = NULL;
		query->AddWHERE( WhereList, complist );
	};

/*
	// Add the order criteria
	XCOrder ord[3];
	long ordlist[3];
	ordlist[0] = FLD_TRANS_NUMBER;
	ordlist[1] = FLD_USER_EXIT_NUMBER;
	ordlist[2] = 0;
	query->AddORDERBY( ordlist, ord );
*/

	// Execute the query
	return vars->dbtxn->ExecuteSQL( query );
};





//@ SEC 3
//@ CHA User Exit Defns Verify
//@ COD UserExitDefnsVerify
//@ TAB USER_EXIT_DEFNS Read
//@ GEN Use UserExitDefnsVerify to verify a User Exit Defns record
void UserExitDefnsVerify( XCBuffer* buf, verify_type verify_mode, XCTransactionVars* vars, XCBuffer* orig ) 
{
	TRANS_INFUNC( UserExitDefnsVerify );

	//@ If verifying an ADD transaction,
	if (verify_mode == VERIFY_ADD) {
		//@ GRS

		//@ SUB ValidateName to check for a valid name
		ValidateName( FLD_USER_EXIT_NAME, vars->buffer, ERR_USER_EXIT, vars );

		//@ SUB LookupNumberFromName to convert system value field name into a system value field number
		//@ ERR C (ALREADY_EXISTS) System Value already exists
		if ( LookupNumberFromName( vars, vars->buffer, buf, FLD_USER_EXIT_NUMBER, FLD_USER_EXIT_NAME, FMT_USER_EXIT_DEFNS ) )
			vars->Errors->Add( ERR_ALREADY_EXISTS, SEV_CRITICAL, FLD_USER_EXIT_NAME, 1, ERR_USER_EXIT );

		//@ GRE
	} else {
		//@ GRS
		
		//@ SUB UserExitRetrieve to verify that we do have a system value with this name
		//@ ERR C (DOESNT_EXIST) System Value doesn't exist
		if ( ! LookupNumberFromName( vars, vars->buffer, buf, FLD_USER_EXIT_NUMBER, FLD_USER_EXIT_NAME, FMT_USER_EXIT_DEFNS ) || 
			!UserExitDefnsRetrieve( buf, vars ))
			vars->Errors->Add( ERR_DOESNT_EXIST, SEV_CRITICAL, FLD_USER_EXIT_NAME, 1, ERR_USER_EXIT );

		//@ GRE
	};

	//@ If verifying an ADD or CHANGE transaction,
	if ( verify_mode == VERIFY_CHANGE || verify_mode == VERIFY_ADD )	{
		//@ GRS
		//@ SUB LookupNumberFromName to convert transaction code into a transaction number.  If it fails,
		//@ ERR C (DOESNT_EXIST) Transaction doesn't exist
		XCBuffer* useme = orig ? orig : buf;
		if ( ! LookupNumberFromName( vars, vars->buffer, useme, FLD_TRANS_NUMBER, FLD_TRANS_CODE, FMT_TRANSACTION_DEFN ) )
			vars->Errors->Add( ERR_DOESNT_EXIST, SEV_CRITICAL, FLD_TRANS_CODE, 1, ERR_TRANSACTION );
		//@ GRE
	};

	TRANS_OUTFUNC();
};


//@ SEC 3
//@ CHA User Exit Defns Change
//@ COD UserExitDefnsChange
//@ TAB USER_EXIT_DEFNS Write
//@ GEN Use to alter User Exit Defns records
void UserExitDefnsChange( XCBuffer* input, XCBuffer* orig, XCTransactionVars* vars )
{
	TRANS_INFUNC( UserExitDefnsChange );

	XCSQLGen* query = vars->query;

	//@ Update the record
	query->MakeFull( SQL_STMT_UPDATE, input, orig );
	vars->dbtxn->ExecuteSQL( query, SQL_NO_RESULT );

	TRANS_OUTFUNC();
};



//@ SEC 3
//@ CHA User Exit Defns Retrieve
//@ COD UserExitDefnsRetrieve
//@ TAB USER_EXIT_DEFNS Read
//@ GEN Use UserExitDefnsRetrieve to retrieve User Exit Defns records
bool UserExitDefnsRetrieve( XCBuffer* buf, XCTransactionVars* vars ) 
{
	TRANS_INFUNC( UserExitDefnsRetrieve );

	bool result;
	XCDBStatement* stmt = NULL;
	XCSQLGen* query = vars->query;

	try {
		query->MakeFull( SQL_STMT_SELECT, buf );
		stmt = vars->dbtxn->ExecuteSQL( query );
		result = (!stmt->Eof());
	} catch( ... ) {
		App->CleanupObjects( 1, &stmt );
		throw;
	};
	App->CleanupObjects( 1, &stmt );

	TRANS_OUTFUNCRET( result );
};



//@ SEC 3
//@ CHA UserExit Defn Delete All
//@ COD UserExitDefnDeleteAll
//@ TAB USER_EXIT_DEFNS Write
//@ GEN Use UserExitDefnDeleteAll to remove fields
void UserExitDefnDeleteAll( XCBuffer* input, XCTransactionVars* vars ) {
	XCSQLGen* query = vars->query;
	XCBuffer* fields = NULL;

	TRANS_INFUNC( FieldDescDeleteAll );

	try {
		fields = App->CreateBuffer( FMT_USER_EXIT_DEFNS, false );
		fields->MoveField( input, FLD_APPL_NBR );

		//@ Delete FIELD_DESCRIPTOR records
		query->MakeDELETE( fields );
		query->AddWHERE( 1, fields->GetField( FLD_APPL_NBR ) );

		vars->dbtxn->ExecuteSQL( query, SQL_NO_RESULT );
	} catch( ... ) {
		App->CleanupObjects( 1, &fields );
		throw;
	};
	App->CleanupObjects( 1, &fields );

	TRANS_OUTFUNC();
};
